package SMUVE;

import java.io.*;
import java.net.*;
import java.util.concurrent.*;
import static SMUVE.Debug.*;

public class Msg_Pipe {
	String player;
	boolean ready;
	private DataOutputStream out;
	private DataInputStream in;
	//private BufferedReader in;
	//private PrintWriter out;
	public static final String delimiter = "|";
	public static final String success = "success";
	public static final String failure = "failure";

	public Msg_Pipe(Socket sock) throws IOException {
		player = "";
		out= new DataOutputStream(sock.getOutputStream());
		in= new DataInputStream(sock.getInputStream());
		//out = new PrintWriter(sock.getOutputStream(), true);
		//in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
		try {
			Thread.sleep(100);
		}
		catch (InterruptedException e) {
		}
		finally {
			ready = true;
		}
	}

	/* Public methods */
	public boolean ready() {
		return(ready);
	}

	public int available() throws IOException {
		return(in.available());
		//return(in.ready() ? 1 : 0);
	}
		
	public static String get_delimiter() {
		return(delimiter);
	}

	public boolean send_message(String msg) {
		boolean retval = true;

		//debug("sending message: " + msg);
		try {
			out.writeUTF(msg);
			out.flush();
			//out.println(msg);
		}
		catch (IOException e) {
			retval = false;
		}
		finally {
			return(retval);
		}
	}

	public String recv_message() {
		String msg = "EXCEPTION";
		try {
			//debug("receiving message ...");
			msg = in.readUTF();
			//msg = in.readLine();
			//debug("receiving  message: " + msg);
		}
		catch (IOException e) {
			debug("IOException");
			e.printStackTrace();
		}
		finally {
			return(msg);
		}
	}

	public String send_recv_message(String msg) {
		send_message(msg);
		return(recv_message());
	}

	public static String get_message_type(String str) {
		String res[] = str.split("\\" + delimiter);
		return(res[0]);
	}

	public static String get_message_body(String str) {
		int index = str.indexOf(delimiter);
		String ret = "";

		if (index >= 0 && index <= str.length())
			ret = str.substring(index + 1);  // start after the delimiter

		return(ret);
	}

	public void close() {
		try {
			in.close();
			out.close();
		}
		catch (IOException e) {
			// do nothing
		}
	}

	public static String[] parse_message(String str) {
		return(str.split("\\" + delimiter));
	}

	/* Client accessible messages */
	public boolean pick_up_item(String player, String item) {
		String m = "pick_up_item" + delimiter + player +
			delimiter + item;
		return(send_recv_message(m).equals(success));
	}

	public boolean put_down_item(String player, String item) {
		String m = "put_down_item" + delimiter + player +
			delimiter + item;
		return(send_recv_message(m).equals(success));
	}

	public boolean add_item(Item item) {
		String m = "add_item" + delimiter + item.get_name() + delimiter +
			item.get_location() + delimiter + item.get_description();
		return(send_recv_message(m).equals(success));
	}

	public String get_item(String item) {
		String m = "get_item" + delimiter + item;
		return(send_recv_message(m));
	}

	public String[] get_room_items(String room) {
		String m = "get_room_items" + delimiter + room;
		String[] result = null;
		String resp = send_recv_message(m);

		if (get_message_type(resp).equals(success)) {
			result = parse_message(get_message_body(resp));
		}

		return(result);
	}

	public String[] get_player_items(String player) {
		String m = "get_player_items" + delimiter + player;
		String[] result = null;
		String resp = send_recv_message(m);

		if (get_message_type(resp).equals(success)) {
			result = parse_message(get_message_body(resp));
		}

		return(result);
	}

	public String get_current_room(String player) {
		String m = "get_current_room" + delimiter + player;
		String retval = "";
		String resp = send_recv_message(m);
		if (get_message_type(resp).equals("success"))
			retval = get_message_body(resp);

		return(retval);
	}

	public boolean login(String player, String password) {
		String m = "login" + delimiter + player + delimiter + password;
		String resp = send_recv_message(m);
		boolean retval = false;

		if (resp.equals("success")) {
			retval = true;
			if (!player.equals("server"))
				this.player = player;
		}

		return(retval);
	}

	public boolean logout(String player) {
		String m = "logout" + delimiter + player;
		return(send_recv_message(m).equals("success"));
	}


	public boolean chat_player(String player, String to_player, String msg) {
		String m = "chat" + delimiter + player + delimiter +
			to_player + delimiter + msg;
		return(send_recv_message(m).equals("success"));
	}

	public boolean chat_room(String player, String to_room, String msg) {
		String m = "chat_room" + delimiter + player + delimiter +
			to_room + delimiter + msg;
		return(send_recv_message(m).equals("success"));
	}

	/* Admin Client methods */
	public boolean add_room(Room room) {
		String msg = "add_room" + delimiter + room.get_name() + delimiter +
			room.get_description();
		return(send_recv_message(msg).equals("success"));
	}

	public boolean add_player(Player player) {
		String msg = "add_player" + delimiter + player.get_name() +
			delimiter + player.get_room() + delimiter + player.get_password();
		return(send_recv_message(msg).equals("success"));
	}

	public String[] get_players() {
		String msg = "get_players";
		String[] result = null;

		String resp = send_recv_message(msg);
		if (get_message_type(resp).equals("success")) 
			result = parse_message(get_message_body(resp));

		return(result);
	}

	public Player get_player(String name) {
		String msg = "get_player" + delimiter + name;
		String resp = send_recv_message(msg);
		String type = get_message_type(resp);
		Player p = null;

		if (type.equals("success")) {
			String body = get_message_body(resp);
			String result[] = parse_message(body);
			if (result.length == 3) {
				String room = result[1];
				String password = result[2];
				p = new Player(name, room, password);
			}
		}

		return(p);
	}

	public String[] get_rooms() {
		String msg = "get_rooms";
		String[] result = null;
		String resp = send_recv_message(msg);

		if (get_message_type(resp).equals("success"))
			result = parse_message(get_message_body(msg));

		return(result);
	}

	public String get_room(String room){
		String msg = "get_room" + delimiter + room;
		return(send_recv_message(msg));
	}
	
	public String move(String name, String to_room) {
		String msg = "move" + delimiter + name + delimiter + to_room;
		return(send_recv_message(msg));
	}

	public String get_room_players(String room) {
		String msg = "get_room_players" + delimiter + room;
		return(send_recv_message(msg));
	}

	public String get_portals(String room) {
		String msg = "get_portals" + delimiter + room;
		return(send_recv_message(msg));
	}

	public boolean add_portal(String room, String to_room, String to_server,
			int to_cport, int to_uport, boolean local_only) {
		String msg = "add_portal" + delimiter + room + delimiter + to_room +
			delimiter + to_server + delimiter + to_cport + delimiter + to_uport +
			delimiter + local_only;
		return(get_message_type(send_recv_message(msg)).equals("success"));
	}
	public boolean remove_portal(String room, String to_room) {
		String msg = "remove_portal" + delimiter + room + delimiter + to_room;
		return(get_message_type(send_recv_message(msg)).equals("success"));
	}
		
	/* Private methods */
}
